/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.agi.ia.kohonen;

/**
 *
 * @author renatogrosz
 */
public class Camada {
    protected Tamanho tcamada,tentrada;
    protected Neuron[][] camada;
    
    protected Tamanho vencedor;
    
    public Camada(TamanhoCamada tamanho, InicializadorDados inicializador){
        
        
        tcamada=tamanho.getCamada();
        tentrada=tamanho.getEntrada();
        camada=new Neuron[tcamada.x][tcamada.y];        
        
        //InicializadorDados inicializador=new InicializadorDadosPadrao();
        int i,j;
        for(i=0;i<tcamada.x;i++){
            for(j=0;j<tcamada.y;j++){
                camada[i][j]=new Neuron(tentrada);
                inicializador.setDadosInicializaveis(camada[i][j]);
                inicializador.iniciarDados();                
            }
        }
    }
    
    public void calcularEntrada(double[][] entrada){
        int i,j;
        for(i=0;i<tcamada.x;i++){
            for(j=0;j<tcamada.y;j++){
                camada[i][j].calcularEntrada(entrada);                
            }
        }
    }
    
    
    public void calcularVencedor(){
        int i,j;
        int x,y;
        
        double euclidiana;
        
        euclidiana=camada[0][0].euclidiana;
        x=0;
        y=0;        
        for(i=0;i<tcamada.x;i++){
            for(j=0;j<tcamada.y;j++){
                if(camada[i][j].euclidiana<euclidiana){
                    x=i;
                    y=j;
                    euclidiana=camada[i][j].euclidiana;
                }                
            }
        }
        vencedor=new Tamanho(x,y);        
    }
    
    
    public Tamanho getVencedor(){
        return vencedor;
    }

    
    public Dados getMatrixDistancia(){
        DadosVO retorno;
        double[][] dados;
        int i,j;
        retorno=new DadosVO();
        dados=new double[tcamada.x][tcamada.y];
        retorno.setTamanho(tcamada);
        retorno.setDados(dados);
        
        for(i=0;i<tcamada.x;i++){
            for(j=0;j<tcamada.y;j++){
                dados[i][j]=camada[i][j].euclidiana;
            }
        }
        return(retorno);
    }
    
    public Dados getNeoronioVencedor(){
        Dados retorno;
        int i,j;
        i=vencedor.x;
        j=vencedor.y;
        
        retorno=camada[i][j];
        return(retorno);
    }
        
        
    public void atualizarCamada(double fator){
        int i;
        int j;
        double d;
        
        for(i=0;i<tcamada.x;i++){
            double dx;
            dx=vencedor.x-i;
            dx=dx*dx;
            for(j=0;j<tcamada.y;j++){
                double dy;
                double f;
                dy=vencedor.y-j;
                dy=dy*dy;
                d=dx+dy;
                f=1 / ( (d/fator) + 1);
                camada[i][j].atualizar(f);
            }
        }
    }
    
    
    public void setFatorAtualizacao(double fator){
        int i,j;
        for(i=0;i<tcamada.x;i++){
            for(j=0;j<tcamada.y;j++){
                camada[i][j].setFatorAtualizacao(fator);                
            }
        }
    }
}
